package com.ct.utils.jwt;

import com.ct.utils.DateUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Jwt工具类
 * Created by RubinChu on 2021/1/22 下午 4:11
 */
public class JwtUtil {

    public static final Long EXPIRE_TIME =  7 * 24* 60 *60 * 1000L ;
    public static final Long ONE_EXPIRE_TIME =  1 * 24 * 60 *60L  ;

    /**
     * 秘钥
     */
    private final static String JWT_PRIVATE_KEY = "KX0CB16040A41140E48F2F";

    /**
     * 刷新时间
     */
    public final static String RENEWAL_TIME = "RENEWAL_TIME";
    public final static String ADMIN_LOGIN_USER_ID = "ADMIN_LOGIN_USER_ID";
    public final static String ADMIN_LOGIN_USER_AVATAR = "ADMIN_LOGIN_USER_AVATAR";
    public final static String IS_ADMIN = "IS_ADMIN";
    public final static String SYSTEM_ID = "SYSTEM_ID";
    public final static String SYSTEM_CODE = "SYSTEM_CODE";
    public final static String SYSTEM_NAME = "SYSTEM_NAME";

    /**
     * 生成token
     *
     * @param account
     * @param avatar
     * @param userId
     * @return
     */
    public static Map<String,String> generateToken(String account,String username,String avatar,String isAdmin, Long userId,
                                                   Long systemId,String sysname,String syscode) {
        String token = Jwts.builder()
                .setSubject(account)
                .setAudience(username)
                .claim(ADMIN_LOGIN_USER_ID, userId)
                .claim(IS_ADMIN, isAdmin)
                .claim(SYSTEM_ID, systemId)
                .claim(SYSTEM_NAME, sysname)
                .claim(SYSTEM_CODE, syscode)
                .claim(ADMIN_LOGIN_USER_AVATAR, avatar)
                .claim(RENEWAL_TIME, new Date(System.currentTimeMillis() + (EXPIRE_TIME * 2)))
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE_TIME))
                .signWith(SignatureAlgorithm.HS256, JWT_PRIVATE_KEY)
                .compact();
        Map<String,String> map = new HashMap<>();
        map.put("token",token);
        map.put("refreshTime", DateUtils.format(new Date(System.currentTimeMillis() + EXPIRE_TIME * 2),DateUtils.DATE_TIME_FORMAT));
        return map;
    }

    public static Map<String,String> generateToken(UserInfo userInfo) {
        return generateToken(userInfo.getAccount(),userInfo.getUsername(),userInfo.getAvatar(),userInfo.getAdmin(),userInfo.getId(),userInfo.getSystemId()
                ,userInfo.getSystemName(),userInfo.getAppid());
    }

    /**
     * 解析token
     *
     * @param token
     * @return
     */
    public static <T> T analyzeToken(String token, String claimKey) {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        try {
            Claims claims = Jwts.parser().setSigningKey(JWT_PRIVATE_KEY).parseClaimsJws(token).getBody();
            return (T) claims.get(claimKey);
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 解析token
     *
     * @param token
     * @return
     */
    public static UserInfo analyzeToken(String token) {
        if (StringUtils.isBlank(token)) {
            return null;
        }
        try {Claims claims = Jwts.parser().setSigningKey(JWT_PRIVATE_KEY).parseClaimsJws(token).getBody();
            UserInfo userInfo = new UserInfo();
            userInfo.setToken(token);
            userInfo.setRenwalTime(DateUtils.format(claims.get(RENEWAL_TIME,Date.class),DateUtils.DATE_TIME_FORMAT));
            userInfo.setAdmin(claims.get(IS_ADMIN,String.class));
            userInfo.setAccount(claims.getSubject());
            userInfo.setUsername(claims.getAudience());
            userInfo.setId(claims.get(ADMIN_LOGIN_USER_ID,Long.class));
            userInfo.setAvatar(claims.get(ADMIN_LOGIN_USER_AVATAR,String.class));
            userInfo.setSystemName(claims.get(SYSTEM_NAME,String.class));
            userInfo.setAppid(claims.get(SYSTEM_CODE,String.class));
            userInfo.setSystemId(claims.get(SYSTEM_ID,Long.class));
            return userInfo;

        } catch (Exception ex) {
            // 这里就是token过期返回的位置
            return null;
        }
    }


}
